package com.leinao.interceptor;

import java.text.DecimalFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.leinao.commons.Response;
import com.leinao.config.EnvironmentConfig;
import com.leinao.config.RedisCacheConfig;
import com.leinao.constant.Constant;
import com.leinao.constant.LoginEnum;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;


/**
 * 
 * 在访问controller前判断是否登录，返回json，不进行重定向。
 * @return true-继续往下执行，false-该filter过滤器已经处理，不继续执行其他过滤器
 * @throws Exception
 * @author  wangshoufa
 * @date 2018年11月15日 下午1:30:19
 *
 */
@Component
@Aspect
public class SecurityAuthInterceptor {

	private static final Logger logger = LoggerFactory
			.getLogger(SecurityAuthInterceptor.class);
	@Autowired
	public HttpServletRequest request;

	@Autowired
	RedisCacheConfig redisCacheConfig;

	@Autowired
	EnvironmentConfig env;

	@Pointcut("execution(* com.leinao.*.controller.*.*(..)) ")
	public void loginJudgementControllerMethodPointcut() {
		logger.debug("loginJudgementControllerMethodPointcut用户是否登陆切面");
	}

	@SuppressWarnings("unchecked")
	@Around("loginJudgementControllerMethodPointcut()")
	public Response<Object> loginInterceptor(ProceedingJoinPoint pjp)
			throws Throwable {
		// 获取请求uri
		HttpServletRequest apiRequest = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		String apiUrl = apiRequest.getRequestURI();
		Object[] args = pjp.getArgs();
		Response<Object> returnMsg = new Response<Object>();
		// 返回当前连接点签名的名称 当前方法的名称
		String methodName = pjp.getSignature().getName();
		if (methodName.startsWith("login") || methodName.startsWith("v2Login")
				|| methodName.startsWith("addTeamMemberByUrl")
				|| methodName.startsWith("checkUrlData")) {
			try {
				returnMsg = (Response<Object>) pjp.proceed(args);
				logger.info("OUT Response------" + methodName + ":" + returnMsg);
			} catch (Throwable e) {
				logger.error("get requestBody failed");
				logger.error(e.getMessage(), e);
			}
			return returnMsg;
		}
		String token = request.getHeader(Constant.USER_TOKEN);
		if (StringUtils.isBlank(token)) {
			token = request.getParameter(Constant.USER_TOKEN);
		}
		String bitaToken = request.getHeader(Constant.USER_BITA_TOKEN);
		if (StringUtils.isBlank(bitaToken)) {
			bitaToken = request.getParameter(Constant.USER_BITA_TOKEN);
		}
		logger.info("pai token: {}, bitaToken:{}", token, bitaToken);
		// 认证用户信息
		Jedis jedis = null;
		try {
			HttpSession session = request.getSession();
			String obj = (String) session
					.getAttribute(Constant.USER_SESSION_KEY);
			if (StringUtils.isBlank(obj)) {
				logger.info("file center get redisResource start");
				JedisPool jedisPool = redisCacheConfig.getJedisPool();
				jedis = jedisPool.getResource();
				logger.info("file center get redisResource end");
				String bitaKey = env.getPrefix() + bitaToken;
				String paiKey = env.getPrefix() + token;
				String bitaResu = jedis.get(bitaKey);
				String paiResu = jedis.get(paiKey);
				if (StringUtils.isBlank(bitaResu)
						|| StringUtils.isBlank(paiResu)) {
					logger.info("redis token data bitaResu: {}, paiResu: {}",
							bitaResu, paiResu);
					return Response.error(Constant.RESPONSE_STATUS_SUCCESS,
							LoginEnum.LOGIN_TIMEOUT.getSeq(),
							LoginEnum.LOGIN_TIMEOUT.getDesc(), null);
				}
				session.setMaxInactiveInterval(env.getExpireSeconds());
				session.setAttribute(Constant.USER_SESSION_KEY, paiResu);
			}
		} catch (JedisException e) {
			logger.error("get redisResource failed", e);
			return Response.error(Constant.RESPONSE_STATUS_SUCCESS,
					LoginEnum.LOGIN_FAILED.getSeq(),
					LoginEnum.LOGIN_FAILED.getDesc(), null);
		} catch (Exception e) {
			logger.error("Analysis user token failed", e);
			return Response.error(Constant.RESPONSE_STATUS_SUCCESS,
					LoginEnum.UNKNOWN_ERROR.getSeq(),
					LoginEnum.UNKNOWN_ERROR.getDesc(), null);
		} finally {
			if (jedis != null) {
				logger.info("close redis");
				jedis.close();
			}
		}

		try {

			// 开始时间
			long beginTime = System.currentTimeMillis();
			String className = pjp.getSignature().getDeclaringTypeName();
			returnMsg = (Response<Object>) pjp.proceed(args);
			logger.debug("OUT Response------" + methodName + ":" + returnMsg);
			long endTime = System.currentTimeMillis();
			DecimalFormat df = new DecimalFormat("0.000");
			String timeConsuming = df
					.format(((float) (endTime - beginTime)) / 1000);
			logger.info("接口耗时统计:【访问的类名=" + className + ";URI=" + apiUrl
					+ ";耗时=" + timeConsuming + "秒】");

		} catch (Throwable e) {
			logger.error("get requestBody failed", e);
			return Response.error(Constant.RESPONSE_STATUS_SUCCESS,
					LoginEnum.DATA_GET_ERROR.getSeq(),
					LoginEnum.DATA_GET_ERROR.getDesc(), null);
		}
		return returnMsg;
	}


}